package com.csi.bumblebee.service.impl;

import com.csi.bumblebee.domain.user.Resume;
import com.csi.bumblebee.domain.user.Student;
import com.csi.bumblebee.mapper.ResumeMapper;
import com.csi.bumblebee.mapper.StudentMapper;
import com.csi.bumblebee.service.AccountRoleService;
import com.csi.bumblebee.service.StudentService;
import com.csi.bumblebee.service.UserStorageService;
import com.csi.bumblebee.util.IdUtil;
import com.csi.bumblebee.util.JwtUtil;
import com.csi.bumblebee.util.MD5Utils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.csi.bumblebee.domain.user.Student.*;

/**
 * student表业务实现类
 *
 * @author HUOJT yeebs(前台根据用户名查用户是否存在
 * )
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class StudentServiceImpl implements StudentService {

    @Autowired
    private AccountRoleService accountRoleService;

    @Autowired
    @Qualifier("jdkRedisTemplate")
    private RedisTemplate<String, Serializable> redisTemplate;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private ResumeMapper resumeMapper;

    @Autowired
    private UserStorageService userStorageService;

    @Override
    public boolean register(Student studentR) {

        boolean result = false;

        Student student = new Student();
        student.setPassword(studentR.getPassword());
        student.setUsername(studentR.getUsername());

        // 设置id
        student.setId(IdUtil.getString(PRE_NAME));

        if(accountRoleService.insertStudent(student.getId()) == 0) {
            return false;
        }

        // 密码加密
        student.setPassword(MD5Utils.str2MD5(student.getPassword()));

        // 成功注册
        if (studentMapper.insertStudent(student) == 1) {

            // 放置redis
            redisPut(student);
            result = true;

            // 新建简历
            Resume resume = new Resume();
            resume.setStudentId(student.getId());
            resume.setId(IdUtil.getString(Resume.PRE_NAME));

            resumeMapper.addResume(resume);

        }
        return result;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public Student login(Student student) {

        // 密码加密
        student.setPassword(MD5Utils.str2MD5(student.getPassword()));

        // 去mysql取
        Student studentMysql = studentMapper.findByUsernamePassword(student);

        // 登录成功
        if (studentMysql != null) {

            // token
            studentMysql.setToken(JwtUtil.createToken(student.getUsername(), "student", 1));

            System.out.println("------------------>   学生id" + studentMysql.getId());

            // 设置storage过期时间
            System.out.println(" ======= " + userStorageService.setExpTimeInRedis(studentMysql.getId(), 1));

            // 从redis取
            Student studentRedis = redisGet(studentMysql.getId());

            // 放置到redis
            if (studentRedis == null) {
                redisPut(studentMysql);
            }
        }
        return studentMysql;
    }

    @Override
    public boolean updateInfo(Student student) {

        boolean result = false;

        if(student.getPassword() != null && !"".equals(student.getPassword())) {
            student.setPassword(MD5Utils.str2MD5(student.getPassword()));
        }

        // 删除redis
        Student studentRedis = redisDelete(student.getId());

        // mysql更新
        if (studentMapper.updateStudent(student) == 1) {

            // 更新redis
            redisPut(studentMapper.findByStudentId(student.getId()));
            result = true;

            // 放回redis老数据
        } else {
            redisPut(studentRedis);
        }
        return result;
    }

    @Override
    public boolean updateStatus(Student student) {
        boolean result = false;

        // 删除redis
        Student studentRedis = redisDelete(student.getId());

        // mysql更新
        if (studentMapper.updateStudentStatus(student) == 1) {

            // 更新redis
            redisPut(studentMapper.findByStudentId(student.getId()));
            result = true;

            // 放回redis老数据
        } else {
            redisPut(studentRedis);
        }
        return result;
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public PageInfo<Student> listInfo(int pageNum, int pageSize, Student student) {

        // 分页
        PageHelper.startPage(pageNum, pageSize);
        return new PageInfo<>(studentMapper.listInfo(student));
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public Student findByStudentId(String id) {

        // 从redis取
        Student student = redisGet(id);

        // 从mysql取
        if (student == null) {
            student = studentMapper.findByStudentId(id);

            // 写入redis
            if (student != null) {
                redisPut(student);
            }
        }

        return student;
    }

    @Override
    public boolean deleteByStudentId(String id) {

        boolean result = false;

        // 删除redis
        Student student = redisDelete(id);

        // 删除mysql
        if (studentMapper.deleteByStudentId(id) == 1) {
            result = true;
        } else {

            // 删除失败，则写回redis原数据
            redisPut(student);
        }

        return result;

    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public int hasJobType(String id) {
        return studentMapper.hasJobType(id);
    }

    @Override
    @Transactional(propagation = Propagation.NOT_SUPPORTED, readOnly = true)
    public int countJobExam(Student student) {
        return studentMapper.countJobExam(student);
    }

    /**
     * 根据用户名查询student
     *
     * @param username 用户名
     * @return student对象
     */
    @Override
    public Student findByName(String username) {
        return studentMapper.findByName(username);
    }

    /**
     * 展示所有学生的账号
     * @return List<Student>
     */
    @Override
    public List<Student> listStudentAccount() {
        return studentMapper.listStudentAccount();
    }

    /**
     * 封禁学生账号
     * @param id 学生Id
     * @return 影响行数
     */
    @Override
    public int bStudentAccount(String id) {
        int result = studentMapper.bStudentAccount(id);

        if (result > 0){
            Student student = studentMapper.findById(id);
            redisTemplate.opsForValue().set(id, student);
        }
        return result;
    }

    /**
     * 删除一个学生账号
     * @param id 主键Id
     * @return 影响行数
     */
    @Override
    public int delete(String id) {
        Student student = (Student) redisTemplate.opsForValue().get(id);
        int result = studentMapper.delete(id);
        if (result > 0) {
            if (student != null){
                redisTemplate.delete(id);
            }
        }
        return result;
    }

    /**
     * 展示所有封禁的账号
     * @return List<Student>
     */
    @Override
    public List<Student> listStudentBlackAccount() {
        return studentMapper.listStudentBlackAccount();
    }

    @Override
    public int releaseAccount(String id) {

        Student student = (Student) redisTemplate.opsForValue().get(id);
        int result = studentMapper.releaseAccount(id);
        if (result > 0) {
            if (student != null) {
                student = studentMapper.findById(id);
                redisTemplate.opsForValue().set(id, student);
            }else {
                redisTemplate.opsForValue().set(id, student);
            }
        }
        return result;
    }

    /**
     * 分页 展示所有已注销的账号
     * @param currentPage 当前页
     * @param perPageSize 每页的数据大小
     *
     * @return PageInfo<Student>
     */
    @Override
    public PageInfo<Student> listCanceledAccount(int currentPage, int perPageSize){

        PageHelper.startPage(currentPage, perPageSize);
        List<Student> students = studentMapper.listCanceledAccount();
        return new PageInfo<>(students);
    }

    /**
     * 后台注销某个账号
     * @param id 主键Id
     * @return 影响行数
     */
    @Override
    public int cancelAccount(String id) {

        int result = studentMapper.cancelAccount(id);
        if (result > 0) {
            redisTemplate.delete(id);
        }
        return result;
    }

    /**
     * 放入redis
     *
     * @param student 学生对象
     */
    private void redisPut(Student student) {
        redisTemplate.opsForValue().set(student.getId(), student, getExpireTime(), TimeUnit.SECONDS);
    }

    /**
     * 从redis取数据
     *
     * @param id 学生id
     * @return 学生对象
     */
    private Student redisGet(String id) {
        redisTemplate.expire(id, getExpireTime(), TimeUnit.SECONDS);
        return (Student) redisTemplate.opsForValue().get(id);
    }

    /**
     * 从redis取数据
     *
     * @param student 学生对象
     * @return 学生对象
     */
    private Student redisGet(Student student) {
        redisTemplate.expire(student.getId(), getExpireTime(), TimeUnit.SECONDS);
        return (Student) redisTemplate.opsForValue().get(student.getId());
    }

    /**
     * 从redis删除
     *
     * @param id 学生id
     * @return 删除的学生
     */
    private Student redisDelete(String id) {
        Student student = redisGet(id);
        redisTemplate.delete(id);
        return student;
    }

    /**
     * 查询学生岗位偏好id
     * @param id 学生id
     * @return 岗位偏好id
     */
    @Override
    public String findByIdJobType(String id) {

        if (id!=null){

            return this.studentMapper.findByIdJobType(id);

        }
        return null;
    }

    private long getExpireTime() {
        return 60 * 60 * 24 * 7;
    }
}

